module clkDiv#(
        parameter CLK_MHZ = 50,        // 主时钟频率（单位：MHz）
        parameter LED_MS = 100, // LED闪烁间隔0.1s(单位：ms)
        parameter SCAN_MS = 1, // 扫描时钟间隔1ms
        parameter DEBOUNCE_MS = 20, // 按键消抖20ms
        parameter TIMER_MS = 1000 // 定时器每秒-1，间隔1s=1000ms
)(
    input logic clk,
    output logic clk_led,
    output logic clk_scan,
    output logic clk_debounce,
    output logic clk_timer
);

// 计算所需时钟周期数和计数器位宽
//1.LED闪烁间隔
localparam LED_MAX = (LED_MS * CLK_MHZ * 1000)/2;
localparam LED_WIDTH = $clog2(LED_MAX) + 1; 

//2.扫描时间间隔
localparam SCAN_MAX = (SCAN_MS * CLK_MHZ * 1000)/2;
localparam SCAN_WIDTH = $clog2(SCAN_MAX) + 1; 

//3.按键消抖间隔
localparam DEBOUNCE_MAX = (DEBOUNCE_MS * CLK_MHZ * 1000)/2;
localparam DEBOUNCE_WIDTH = $clog2(DEBOUNCE_MAX) + 1; 

//4.定时器时间间隔（1s）
localparam TIMER_MAX = (TIMER_MS * CLK_MHZ * 1000)/2;
localparam TIMER_WIDTH = $clog2(TIMER_MAX) + 1; 

//计数器
logic [LED_WIDTH-1:0] counter_led;
logic [SCAN_WIDTH-1:0] counter_scan;
logic [DEBOUNCE_WIDTH-1:0] counter_debounce;
logic [TIMER_WIDTH-1:0] counter_timer;


always_ff @(posedge clk) begin
    //LED时钟分频
    if(counter_led == LED_MAX-1)begin //计数达到阈值
        clk_led<=~clk_led; //翻转时钟信号
        counter_led<=0; //计数器清零
    end else begin
        counter_led<=counter_led+1;
    end

    //扫描时钟分频
    if(counter_scan == SCAN_MAX-1)begin //计数达到阈值
        clk_scan<=~clk_scan; //翻转时钟信号
        counter_scan<=0; //计数器清零
    end else begin
        counter_scan<=counter_scan+1;
    end

    //按键消抖分频
    if(counter_debounce == DEBOUNCE_MAX-1)begin //计数达到阈值
        clk_debounce<=~clk_debounce; //翻转时钟信号
        counter_debounce<=0; //计数器清零
    end else begin
        counter_debounce<=counter_debounce+1;
    end

    //定时器时间间隔
    if(counter_timer == TIMER_MAX-1)begin //计数达到阈值
        clk_timer<=~clk_timer; //翻转时钟信号
        counter_timer<=0; //计数器清零
    end else begin
        counter_timer<=counter_timer+1;
    end

end
endmodule